﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading.Tasks;
using System.Windows;

using Client.Common;
using Client.DAL;

using Microsoft.Win32;

using Models;

using Newtonsoft.Json;

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

using Panuon.UI.Silver;

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;

namespace Client.ViewModels
{
    public class ChargeDetailRptViewModel : BindableBase, IRegionMemberLifetime
    {
        public bool KeepAlive => false;

        #region 绑定属性

        //载入中显示
        private Visibility _running;

        public Visibility Running
        {
            get { return _running; }
            set { SetProperty(ref _running, value, "Running"); }
        }

        //载入图标
        private bool _runPic;

        public bool RunPic
        {
            get { return _runPic; }
            set { SetProperty(ref _runPic, value, "RunPic"); }
        }

        //客户类别
        private ObservableCollection<CustomCateModel> _cateList;

        public ObservableCollection<CustomCateModel> CateList
        {
            get { return _cateList; }
            set { SetProperty(ref _cateList, value, "CateList"); }
        }

        //选择的类别
        private object _selectedCate;

        public object SelectedCate
        {
            get { return _selectedCate; }
            set { SetProperty(ref _selectedCate, value, "SelectedCate"); }
        }

        //客户列表
        private ObservableCollection<CustomModel> _custList;

        public ObservableCollection<CustomModel> CustList
        {
            get { return _custList; }
            set { SetProperty(ref _custList, value, "CustList"); }
        }

        //选择的客户
        private object _selectedCust;

        public object SelectedCust
        {
            get { return _selectedCust; }
            set { SetProperty(ref _selectedCust, value, "SelectedCust"); }
        }

        //产品列表
        private ObservableCollection<ProductModel> _proList;

        public ObservableCollection<ProductModel> ProList
        {
            get { return _proList; }
            set { SetProperty(ref _proList, value, "ProList"); }
        }

        //选择的产品
        private object _selectedPro;

        public object SelectedPro
        {
            get { return _selectedPro; }
            set { SetProperty(ref _selectedPro, value, "SelectedPro"); }
        }

        //报表
        private ObservableCollection<BillEntryModel> _rptList;

        public ObservableCollection<BillEntryModel> RptList
        {
            get { return _rptList; }
            set { SetProperty(ref _rptList, value, "RptList"); }
        }

        //开始时间
        private string _startDate;

        public string StartDate
        {
            get { return _startDate; }
            set { SetProperty(ref _startDate, value, "StartDate"); }
        }

        //结束时间
        private string _endDate;

        public string EndDate
        {
            get { return _endDate; }
            set { SetProperty(ref _endDate, value, "EndDate"); }
        }

        //产品选择框状态
        private bool _cbxProEnable;

        public bool CbxProEnable
        {
            get { return _cbxProEnable; }
            set { SetProperty(ref _cbxProEnable, value, "CbxProEnable"); }
        }

        //类别选择框状态
        private bool _cbxCateEnable;

        public bool CbxCateEnable
        {
            get { return _cbxCateEnable; }
            set { SetProperty(ref _cbxCateEnable, value, "CbxCateEnable"); }
        }

        //客户选择框
        private bool _cbxCustEnable;

        public bool CbxCustEnable
        {
            get { return _cbxCustEnable; }
            set { SetProperty(ref _cbxCustEnable, value, "CbxCustEnable"); }
        }

        #endregion 绑定属性

        #region 属性

        #endregion 属性

        #region 命令

        public DelegateCommand QueryCommand { get; private set; }
        public DelegateCommand ExportCommand { get; private set; }
        public DelegateCommand SelectCateCommand { get; private set; }

        #endregion 命令

        #region 构造函数

        public ChargeDetailRptViewModel()
        {
            Running = Visibility.Hidden;
            RunPic = false;
            CbxProEnable = true;
            CbxCateEnable = true;
            CbxCustEnable = true;
            StartDate = DateTime.Now.ToString("yyyy-MM-dd");
            EndDate = DateTime.Now.ToString("yyyy-MM-dd");
            CateList = new ObservableCollection<CustomCateModel>();
            CustList = new ObservableCollection<CustomModel>();
            ProList = new ObservableCollection<ProductModel>();
            RptList = new ObservableCollection<BillEntryModel>();
            QueryCommand = new DelegateCommand(GetRpt);
            ExportCommand = new DelegateCommand(ExportToXls);
            SelectCateCommand = new DelegateCommand(GetCustList);
            GetProductList();
        }

        #endregion 构造函数

        #region 方法

        //读取产品列表
        private StateModel proState;

        private async void GetProductList()
        {
            ProList.Clear();
            CbxProEnable = false;
            Running = Visibility.Visible;
            RunPic = true;
            void callback(RetModel rm)
            {
                if (proState.CurStep != Steps.Send) return;
                proState.RM = rm;
                proState.RM.Data = rm.Success ? rm.Data is null ? null : JsonConvert.DeserializeObject<List<ProductModel>>(rm.Data?.ToString()) : null;
                proState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            proState = new StateModel { CurStep = Steps.Send };
            ProSrv.GetProList(callback, "", "", 0);
            await proState.CheckState(10);
            if (proState.CurStep == Steps.Succ)
            {
                if (proState.RM.Data is List<ProductModel> l)
                {
                    l.Insert(0, new ProductModel { Id = 0, ProName = "全部", ProCode = "0000" });
                    ProList.AddRange(l);
                    SelectedPro = ProList[0];
                }
            }
            else
                Comm.ShowErr(proState.ErrStr, "读取商品列表");

            CbxProEnable = true;
            Running = Visibility.Hidden;
            RunPic = false;
            GetCateList();
        }

        //读客户类别
        private StateModel cateState;

        private async void GetCateList()
        {
            CateList.Clear();
            Running = Visibility.Visible;
            RunPic = true;
            CbxCateEnable = false;
            void callback(RetModel rm)
            {
                if (cateState.CurStep != Steps.Send) return;
                cateState.RM = rm;
                cateState.RM.Data = rm.Success ? rm.Data is null ? null : JsonConvert.DeserializeObject<List<CustomCateModel>>(rm.Data?.ToString()) : null;
                cateState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            cateState = new StateModel { CurStep = Steps.Send };
            CustomSrv.GetCateList(callback);
            await cateState.CheckState(10);
            if (cateState.CurStep == Steps.Succ)
            {
                if (cateState.RM.Data is List<CustomCateModel> l)
                {
                    l.Insert(0, new CustomCateModel { Id = 0, CateCode = "", CateName = "全部" });
                    CateList.AddRange(l);
                    SelectedCate = CateList[0];
                    //GetCustList();
                }
            }
            else
                Comm.ShowErr(cateState.ErrStr, "读取客户类别");
            Running = Visibility.Hidden;
            RunPic = false;
            CbxCateEnable = true;
        }

        //读客户列表
        private StateModel custState;

        private async void GetCustList()
        {
            Running = Visibility.Visible;
            RunPic = true;
            CbxCustEnable = false;
            CustList.Clear();
            if (SelectedCate is null || !(SelectedCate is CustomCateModel cm))
                return;
            void callback(RetModel rm)
            {
                if (custState.CurStep != Steps.Send) return;
                custState.RM = rm;
                custState.RM.Data = rm.Success ? rm.Data is null ? new List<CustomModel>() : JsonConvert.DeserializeObject<List<CustomModel>>(rm.Data?.ToString()) : null;
                custState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            custState = new StateModel { CurStep = Steps.Send };
            CustomSrv.GetCustList(callback, cm.Id);
            await custState.CheckState(10);
            if (custState.CurStep == Steps.Succ)
            {
                if (custState.RM.Data is List<CustomModel> l)
                {
                    l.Insert(0, new CustomModel { Id = 0, CustName = "全部" });
                    CustList.AddRange(l);
                    SelectedCust = CustList[0];
                }
            }
            else
                Comm.ShowErr(custState.ErrStr, "读取客户列表");
            Running = Visibility.Hidden;
            RunPic = false;
            CbxCustEnable = true;
        }

        //查询报表
        private StateModel rptState;

        private async void GetRpt()
        {
            if (!(SelectedCust is CustomModel cust))
            {
                Comm.ShowErr("必须选择客户！", "兑换记录");
                return;
            }
            if (!(SelectedCate is CustomCateModel cate))
            {
                Comm.ShowErr("必须选择客户类别", "兑换记录");
                return;
            }
            if (!(SelectedPro is ProductModel pro))
            {
                Comm.ShowErr("必须选择产品！", "兑换记录");
                return;
            }
            if (string.IsNullOrEmpty(StartDate) || string.IsNullOrEmpty(EndDate))
            {
                Comm.ShowErr("起止时间不能为空！", "兑换记录");
                return;
            }

            if (pro is null)
            {
                Comm.ShowErr("必须选择客户！", "兑换记录");
                return;
            }
            Running = Visibility.Visible;
            RunPic = true;
            RptList.Clear();
            void callback(RetModel rm)
            {
                if (rptState.CurStep != Steps.Send) return;
                rptState.RM = rm;
                rptState.RM.Data = rm.Success ? rm.Data is null ? null : JsonConvert.DeserializeObject<List<BillEntryModel>>(rm.Data?.ToString()) : null;
                rptState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            rptState = new StateModel { CurStep = Steps.Send };
            BillSrv.GetChargeDetail(callback, StartDate, EndDate, pro.Id, cate.Id, cust.Id);
            await rptState.CheckState(10);
            if (rptState.CurStep == Steps.Succ)
            {
                if (rptState.RM.Data is List<BillEntryModel> l)
                {
                    RptList.AddRange(l);
                }
            }
            else
                Comm.ShowErr(rptState.ErrStr, "兑换记录");
            Running = Visibility.Hidden;
            RunPic = false;
        }

        //导出
        private async void ExportToXls()
        {
            if (RptList.Count < 1)
            {
                Comm.ShowErr("没有要导出的数据", "导出报表");
                return;
            }
            string fileName = "";
            SaveFileDialog f = new SaveFileDialog
            {
                Filter = "Excel 97-2003|*.xls|Excel 2007|*.xlsx",
                FileName = null
            };
            f.ShowDialog();
            if (f.FileName.IsNullOrEmpty())
                return;
            fileName = f.FileName;
            Running = Visibility.Visible;
            RunPic = true;
            string err = "";
            var x = await Task.Run(() =>
            {
                try
                {
                    IWorkbook workBook = null;
                    FileInfo fi = new FileInfo(fileName);
                    if (fi.Extension.ToLower() == ".xlsx")
                        workBook = new XSSFWorkbook();
                    else if (fi.Extension.ToLower() == ".xls")
                        workBook = new HSSFWorkbook();
                    else
                        throw new Exception("文件后缀不正确！");
                    ISheet sheet = workBook.CreateSheet("编码");

                    #region 表头

                    IRow row = sheet.CreateRow(0);
                    row.CreateCell(0).SetCellValue("长编码");
                    row.CreateCell(1).SetCellValue("产品编号");
                    row.CreateCell(2).SetCellValue("产品名");
                    row.CreateCell(3).SetCellValue("客户编号");
                    row.CreateCell(4).SetCellValue("客户名");
                    row.CreateCell(5).SetCellValue("兑换时间");
                    row.CreateCell(6).SetCellValue("经手人");
                    row.CreateCell(7).SetCellValue("金额");

                    #endregion 表头

                    for (int i = 0; i < RptList.Count; i++)
                    {
                        int idx = i + 1;
                        row = sheet.CreateRow(idx);
                        row.CreateCell(0).SetCellValue(RptList[i].CodeFull);
                        row.CreateCell(1).SetCellValue(RptList[i].ProCode);
                        row.CreateCell(2).SetCellValue(RptList[i].ProName);
                        row.CreateCell(3).SetCellValue(RptList[i].ChargeCustCode);
                        row.CreateCell(4).SetCellValue(RptList[i].ChargeCustName);
                        row.CreateCell(5).SetCellValue(RptList[i].ChargeDate);
                        row.CreateCell(6).SetCellValue(RptList[i].ChargeMakerName);
                        row.CreateCell(7).SetCellValue(RptList[i].ChargeAmount.ToString());
                    }
                    //保存文件
                    FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    workBook.Write(fs);
                    fs.Dispose();
                    return true;
                }
                catch (Exception ex)
                {
                    err = ex.Message;
                    return false;
                }
            });
            if (!x)
            {
                Comm.ShowErr(err, "导出报表", MessageBoxIcon.Error);
            }
            Running = Visibility.Hidden;
            RunPic = false;
        }

        #endregion 方法
    }
}